package exp07gui.mine.v2;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MineFrame extends JFrame implements ActionListener {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private static final int MINE = 9;
    static Random r = new Random();
    protected int height;
    protected int width;
    protected int mines;
    protected int a[][];
    protected JButton btnBricks[][];
    protected int cnt;

    protected JPanel minePanel;
    protected JPanel configPanel;

    JTextField txtHeight, txtWidth, txtMines;
    JButton setConfigButton;

    public MineFrame() {
        super("Mine ver 1.0 by ZHAO Jing");

        setLayout(new BorderLayout());
        configPanel = new JPanel();
        configPanel.setLayout(new FlowLayout());
        configPanel.add(new JLabel("Height:"));
        configPanel.add(txtHeight = new JTextField(10));
        configPanel.add(new JLabel("Width:"));
        configPanel.add(txtWidth = new JTextField(10));
        configPanel.add(new JLabel("Mines:"));
        configPanel.add(txtMines = new JTextField(10));
        configPanel.add(setConfigButton = new JButton("OK"));
        setConfigButton.addActionListener(this);
        add(configPanel, BorderLayout.NORTH);
        height = 100;
        width = 100;

        minePanel = new JPanel();
        btnBricks = new JButton[height][width];
        for (int i = 0; i < height; i++)
            for (int j = 0; j < width; j++) {
                btnBricks[i][j] = new JButton();
                btnBricks[i][j].addActionListener(this);
                btnBricks[i][j].setVisible(false);
            }

        this.setSize(800, 600);
        this.setVisible(true);
    }

    void debug() {
        for (int i = 1; i <= height; i++) {
            for (int j = 1; j <= width; j++)
                if (a[i][j] == MINE)
                    System.out.print("* ");
                else if (a[i][j] == 0)
                    System.out.print("  ");
                else
                    System.out.print(a[i][j] + " ");
            System.out.println();
        }
    }

    private void placeMime() {
        for (int i = 0; i < mines; ) {
            int x = r.nextInt(height) + 1;
            int y = r.nextInt(width) + 1;
            if (a[x][y] == 0) {
                ++i;
                a[x][y] = MINE;
            }
        }
        for (int i = 1; i <= height; i++)
            for (int j = 1; j <= width; j++) {
                if (a[i][j] != MINE) {
                    a[i][j] = count8(i, j);
                }
            }

    }

    private int count8(int h, int w) {
        int s = 0;
        for (int i = h - 1; i <= h + 1; i++)
            for (int j = w - 1; j <= w + 1; j++) {
                if (a[i][j] == MINE)
                    ++s;
            }
        return s;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new MineFrame();

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == setConfigButton) {
            setConfigButton.setEnabled(false);
            height = Integer.parseInt(txtHeight.getText());
            width = Integer.parseInt(txtWidth.getText());
            mines = Integer.parseInt(txtMines.getText());
            startGame();

        } else if (e.getSource() instanceof JButton) {
            JButton curButton = (JButton) (e.getSource());
            int x = 0, y = 0;
            for (int i = 0; i < height; i++)
                for (int j = 0; j < width; j++) {
                    if (btnBricks[i][j] == curButton) {
                        x = i + 1;
                        y = j + 1;
                    }
                }

            if (a[x][y] == MINE) {
                for (int i = 0; i < height; i++)
                    for (int j = 0; j < width; j++)
                        if (btnBricks[i][j].isEnabled() && a[i + 1][j + 1] == MINE)
                            btnBricks[i][j].setText(":(");
                JOptionPane.showMessageDialog(null, "Game over!");
                setConfigButton.setEnabled(true);

            } else if (a[x][y] > 0) {
                --cnt;
                curButton.setText(a[x][y] + "");
                curButton.setEnabled(false);
            } else {
                expand(x, y);
            }

            if (cnt == 0) {
                for (int i = 0; i < height; i++)
                    for (int j = 0; j < width; j++)
                        if (btnBricks[i][j].isEnabled()) {
                            btnBricks[i][j].setText(":)");
                            btnBricks[i][j].setEnabled(false);
                        }
                JOptionPane.showMessageDialog(null, "Win");
                startGame();
            }
        }

    }

    private void startGame() {
        cnt = height * width - mines;
        a = new int[height + 2][width + 2];
        placeMime();
        minePanel.setLayout(new GridLayout(width, height));
        for (int i = 0; i < height; i++)
            for (int j = 0; j < width; j++) {
                minePanel.add(btnBricks[i][j]);
                btnBricks[i][j].setEnabled(true);
                btnBricks[i][j].setText("");
                btnBricks[i][j].setVisible(true);
            }

        add(minePanel, BorderLayout.CENTER);
        this.setSize(height * 50 + 90, width * 50 + 25);
        System.out.println(height + " " + width + " " + getSize());
        setVisible(true);

    }

    private void expand(int x, int y) {
        --cnt;
        if (a[x][y] != 0) {
            btnBricks[x - 1][y - 1].setText(a[x][y] + "");
            btnBricks[x - 1][y - 1].setEnabled(false);
            return;
        }
        btnBricks[x - 1][y - 1].setText(a[x][y] + "");
        btnBricks[x - 1][y - 1].setEnabled(false);
        int h = x, w = y;
        for (int i = h - 1; i <= h + 1; i++)
            for (int j = w - 1; j <= w + 1; j++) {
                if (ok(i, j) && btnBricks[i - 1][j - 1].isEnabled())
                    expand(i, j);
            }
    }

    private boolean ok(int x, int y) {
        return x <= height && x >= 1 && y <= width && y >= 1;
    }

}
